var root = {
  val: 1,
  right: {
    val: 2,
    left: {
      val: 3
    }
  }
}

/**
 * 实现的动态过程是
 * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
  var res = []; // 保存遍历的结果
  if (root === null) {
    return res;
  }
  var stack = []; // 维护遍历节点，跟踪节点的栈
  var prev = null;
  while( (stack.length > 0) || (root != null)) {
    while(root != null) { // 一直遍历的是左边的分支
      stack.push(root); // 压入跟踪栈中
      root = root.left;
    }
    root = stack.pop(); // 从跟踪栈中取出一个节点
    if (root.right == null || root.right == prev) { // 判断这个节点是不是没有右子树或者刚刚访问过这个节点的右子树
      res.push(root.val);
      prev = root; // 指向刚刚访问的这个节点
      root = null; // 访问左子树的上一个节点
    } else { // 否则将这个节点压入栈中，然后访问这个节点的右子树
      stack.push(root);
      root = root.right;
    }
  }
  return res;
};

console.log(postorderTraversal(root))